/**
 * 
 */
package pvt.delez.pa.depend;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;

import pam.CombinationLibrary;
import pam.JarLibrary;
import pam.Library;
import pam.PamFactory;
import pam.Project;
import pam.VariableLibrary;


/**
 * 依赖分析的类
 * 
 * @author Administrator
 * 
 */
public class AnalysisProjectDepend {

	private Map<String, Project> analysisedProjects = new HashMap<String, Project>();

	private Map<String, Library> librarys = new HashMap<String, Library>();
	private Set<Project> primaryProjects = new HashSet<Project>();

	public AnalysisProjectDepend() {
	}

	public void addPrimaryProject(Project primary) {
		primaryProjects.add(primary);
	}

	public Set<Project> getPrimaryProjects() {
		return primaryProjects;
	}

	public Collection<Project> getAllProjects() {
		return analysisedProjects.values();
	}

	public Collection<Library> getAllLibrarys() {
		return librarys.values();
	}

	public Project analysis(IJavaProject sysProject) {
		String projectName = sysProject.getProject().getName();
		Project project = analysisedProjects.get(projectName);
		if (project != null) {
			return project;
		}
		project = createProject(projectName);
		build(sysProject, project);
		return project;
	}

	private Project createProject(String projectName) {

		Project project = PamFactory.eINSTANCE.createProject();
		project.setName(projectName);
		analysisedProjects.put(projectName, project);
		return project;
	}

	private Project analysis(IProject depSysProject) {
		IJavaProject depJavaProject = JavaCore.create(depSysProject);
		if (depJavaProject == null) {
			try {
				depJavaProject = (IJavaProject) depSysProject
						.getNature(JavaCore.NATURE_ID);
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
		if (depJavaProject == null) {
			Project project = analysisedProjects.get(depSysProject.getName());
			if (project != null) {
				return project;
			}
			return createProject(depSysProject.getName());
		}
		return analysis(depJavaProject);
	}

	private void build(IJavaProject sysProject, Project project) {
		try {
			IClasspathEntry[] entrys = sysProject.readRawClasspath();
			for (IClasspathEntry e : entrys) {
				String key = e.getPath().toString();
				if (e.getEntryKind() != IClasspathEntry.CPE_PROJECT) {
					if (librarys.containsKey(key)) {
						project.getLibraries().add(librarys.get(key));
						continue;
					}
				}
				switch (e.getEntryKind()) {
				case IClasspathEntry.CPE_PROJECT:
					String depName = e.getPath().toFile().getName();
					IProject depSysProject = ResourcesPlugin.getWorkspace()
							.getRoot().getProject(depName);
					Project depProject = analysis(depSysProject);
					if (depProject != null) {
						project.getDepends().add(depProject);
					}
					break;
				case IClasspathEntry.CPE_CONTAINER:

					CombinationLibrary cl = PamFactory.eINSTANCE
							.createCombinationLibrary();

					cl.setPath(e.getPath().toString());

					IClasspathContainer container = JavaCore
							.getClasspathContainer(e.getPath(), sysProject);
					cl.setName(container == null ? e.getPath().lastSegment()
							: container.getPath().lastSegment());
					if (container != null) {
						IClasspathEntry[] subEntrys = container
								.getClasspathEntries();
						for (IClasspathEntry sub : subEntrys) {
							cl.getPaths().add(sub.getPath().toString());
						}
					}
					project.getLibraries().add(cl);
					librarys.put(key, cl);
					break;

				case IClasspathEntry.CPE_LIBRARY:
					JarLibrary lib = PamFactory.eINSTANCE.createJarLibrary();

					lib.setName(e.getPath().lastSegment());
					lib.setPath(e.getPath().toString());

					project.getLibraries().add(lib);
					librarys.put(key, lib);
					break;

				case IClasspathEntry.CPE_SOURCE:
					break;
				case IClasspathEntry.CPE_VARIABLE:
					IPath path = e.getPath();
					String varName = path.segment(0);

					VariableLibrary var = PamFactory.eINSTANCE
							.createVariableLibrary();
					var.setName(path.lastSegment());
					var.setExtensionPath(path.toString());
					IPath p = JavaCore.getClasspathVariable(varName);
					var.setPath(p == null ? "?" : p.toString());

					project.getLibraries().add(var);
					librarys.put(key, var);
					break;

				default:
					break;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
